//
//  MsgCellBaseModel.swift
//  swiftim
//
//  Created by yangjian on 2023/6/2.
//

import Foundation
import RxSwift

enum IMMsgBodyType : Int{
    case unknown = 0
    case text = 1
    case image
    case video
    case location
    case voice
    case file
    case cmd
    case custom
    case extGif
    case extRecall
    case extCall
    case extNewFriend
    case pictMixText
    case extAddGroup

}

enum MsgCellType : Int{
    case user
    case time
    case system
}
//语音转文字,预留
enum MsgVoiceConvertTextStatus : Int {
    case none   //无
    case converting     //正在转换
    case success    //转换成功
    case failure    //转换失败
} ;


class MsgCellBaseModel{
    
    var imUserid = ""
    var showName = ""
    var headImageURLString = ""
    var defaultHeadImage = UIImage()
    
    var userInfoBag = DisposeBag()
    var rx_messageStatus = BehaviorSubject<EMMessageStatus>(value: .pending)
    var rx_userInfo = BehaviorSubject<EMUserInfo>(value: EMUserInfo())
//    var _message : EMChatMessage
    var message : EMChatMessage
    
    
    var voiceDuration : Int32 = 1
    
    var msgBodyType = IMMsgBodyType.text
    
    var timestamp : Int64 = 0
    
    var cellName = ""
    var cellType = MsgCellType.user
    var show_text = NSAttributedString()
    
    var direction : EMMessageDirection{
        return message.direction
    }
    
    var imageFitSize : CGSize = {
        return CGSize()
    }()
    var text = ""
    var textHeight : CGFloat = 0

    var rx_voicePlaying = BehaviorSubject<Bool>(value: false)
//    var voicePlaying = false
    var voiceConvertText_tempText = ""
    var voiceConvertText_reloading = false
    var voiceConvertText_status = MsgVoiceConvertTextStatus.none
    
    weak var currentCell : MsgBaseCell?
//    weak var currentTableView : UITableView?

    var cellHeight : CGFloat{
        if cellType == .system {
            return self.textHeight + (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindTopAndBottomEdgeSpacing)
        }
        if cellType == .time {
            return MsgCellOtherLayoutAdapterConfig.share.timeMarkerCellHeight;
        }
        
        let cellHeight_subtractMsgContent = MsgCellLayoutAdapterConfig.share.cellHeight_subtractMsgContentHeight(showName: MsgTableViewConfig.share.showName(chatType: message.chatType, direction: message.direction))
        if msgBodyType == .text {
            return self.textHeight + cellHeight_subtractMsgContent
        }
        if msgBodyType == .image {
            return imageFitSize.height + cellHeight_subtractMsgContent
        }
        if msgBodyType == .video {
            return imageFitSize.height + cellHeight_subtractMsgContent
        }
        if msgBodyType == .voice {
            if voiceConvertText_status == .none {
                return MsgCellOtherLayoutAdapterConfig.share.voiceContentViewHeight + cellHeight_subtractMsgContent
            }else{
                //转文字的高度 (需要实时计算)
                let maxWidth = MsgCellLayoutAdapterConfig.share.msgBackgroundWidth() - (2 * MsgCellOtherLayoutAdapterConfig.share.voiceConvertTextEdgeSpacing)
                let textHeight = fitHeight_string(string: text, font: MsgTableViewConfig.share.voiceConvertTextFont, maxWidth: maxWidth)
                return MsgCellOtherLayoutAdapterConfig.share.voiceContentViewHeight + cellHeight_subtractMsgContent + MsgCellOtherLayoutAdapterConfig.share.voiceConvertTextToBottom + textHeight + (2 * MsgCellOtherLayoutAdapterConfig.share.voiceConvertTextEdgeSpacing)
            }
        }
        if msgBodyType == .file {
            return 50 + cellHeight_subtractMsgContent
        }
        if msgBodyType == .location {
            return 126 + cellHeight_subtractMsgContent
        }
        if msgBodyType == .custom {
            let body = self.message.body as! EMCustomMessageBody
            if body.event == "userCard" {
                return MsgCellOtherLayoutAdapterConfig.share.businessCardCellContentHeight + MsgCellLayoutAdapterConfig.share.cellHeight_subtractMsgContentHeight(showName: MsgTableViewConfig.share.showName(chatType: self.message.chatType, direction: self.message.direction))
            }else if body.event == "" {
                return textHeight + MsgCellLayoutAdapterConfig.share.cellHeight_subtractMsgContentHeight(showName: MsgTableViewConfig.share.showName(chatType: self.message.chatType, direction: self.message.direction))
            }else{
                return textHeight + MsgCellLayoutAdapterConfig.share.cellHeight_subtractMsgContentHeight(showName: MsgTableViewConfig.share.showName(chatType: self.message.chatType, direction: self.message.direction))
            }
        }
        return 0
    }
    

    init(message : EMChatMessage) {
        self.message = message
        statusChanged()
        self.cellType = .user;
        msgBodyType = IMMsgBodyType(rawValue: message.body.type.rawValue) ?? .unknown
        if message.body.type == .text {
            if message.ext?[MSG_EXT_GIF] != nil {
                msgBodyType = .extGif
            }else if message.ext?[MSG_EXT_RECALL] != nil {
                msgBodyType = .extRecall
                cellType = .system
                text = "";
                let ext = self.message.ext!
                let recallBy = ext[MSG_EXT_RECALLBY] as! String
                if recallBy == EMClient.shared().currentUsername {
                    text = "我撤回了一条消息";
                } else if recallBy == self.message.from {
                    if (self.message.chatType == .chat) {
                        text = "对方撤回了一条消息"
                    } else {
                        text = "\"\(recallBy)\"撤回了一条消息"
                    }
                } else {
                    text = "\"\(recallBy)\"撤回了来自\"\(self.message.from)\"的一条消息"
                }
            }else if message.ext?[MSG_EXT_NEWNOTI] != nil {
                if message.ext?[MSG_EXT_NEWNOTI] as! String == NOTI_EXT_ADDFRIEND {
                    msgBodyType = .extNewFriend
                    cellType = .system
                    let body = self.message.body as! EMTextMessageBody
                    text = body.text
                }else if  message.ext?[MSG_EXT_NEWNOTI] as! String == NOTI_EXT_ADDGROUP {
                    msgBodyType = .extAddGroup
                    cellType = .system
                    let body = self.message.body as! EMTextMessageBody
                    text = body.text
                }
            }else if message.ext?[MSG_EXT_CALLID] != nil && (message.ext?[MSG_EXT_CALLID] as! String).count > 0 {
                msgBodyType = .extCall;
            }else if message.ext?["conferenceId"] != nil && (message.ext?["conferenceId"] as! String).count > 0 {
                msgBodyType = .extCall;
            }
        }
        self.config()
    }
    
    init(text : String , cellType : MsgCellType) {
        let body = EMCustomMessageBody(event: "im_time", customExt: nil)
        message = EMChatMessage(conversationID: EMClient.shared().currentUsername ?? "", body: body, ext: nil)
        msgBodyType = .custom;
        self.cellType = cellType
        self.text = text
        self.config()
    }
    
    init(timestamp : Int64) {
        let body = EMCustomMessageBody(event: "im_time", customExt: nil)
        message = EMChatMessage(conversationID: EMClient.shared().currentUsername ?? "", body: body, ext: nil)
        msgBodyType = .custom;
        self.cellType = .time
        self.timestamp = timestamp
        self.text = "run"
        self.config()
    }

    
    func config(){
        
        if cellType == .system {
            self.cellName = "MsgSystemRemindCell";
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.systemTextFont, color: UIColor.gray)
            self.textHeight = fitHeight_attributedString(attributedString: self.show_text, maxWidth: SCREEN_WIDTH - (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindLeftAndRightMiniEdgeSpacing))
            return
        }
        if cellType == .time {
            self.cellName = "MsgTimeMarkerCell"
//            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.timeFont, color: UIColor.gray)
            self.textHeight = MsgTableViewConfig.share.timeFont.pointSize
//            fitHeight_attributedString(attributedString: self.show_text, maxWidth: SCREEN_WIDTH - (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindLeftAndRightMiniEdgeSpacing))
            return
        }
        let userInfo = UserInfoStore.share.fetchUserInfo(username: self.message.from)
        var needFetchFromServer = true
        if let username = userInfo.userId {
            if username.count > 0 {
                needFetchFromServer = false
                self.rx_userInfo.onNext(userInfo)
            }
        }
        if needFetchFromServer {
            UserInfoStore.share.fetchUserInfosFromServer(usernames: [self.message.from])
            EMIMHelper.share.userinfoUpdateFinishSubject.subscribe(onNext: {[unowned self] usernames in
                if usernames.contains(self.message.from) {
                    DispatchQueue.main.async {
                        self.rx_userInfo.onNext(UserInfoStore.share.fetchUserInfo(username: self.message.from))
                    }
                    self.userInfoBag = DisposeBag()
                }
            }).disposed(by: userInfoBag)
        }
        
        
        if self.msgBodyType == .text {
            self.cellName = "MsgUserTextCell"
            let body = self.message.body as! EMTextMessageBody
            self.text = body.text
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.textFont, color: UIColor.black)
            self.textHeight =
            fitHeight_attributedString(attributedString: show_text, maxWidth: MsgCellLayoutAdapterConfig.share.msgContentMaxWidth())
        }else if self.msgBodyType == .image {
            self.cellName = "MsgUserImageCell";
            let body = self.message.body as! EMImageMessageBody;
            self.imageFitSize = messageCell_imageSizeToFitSize(imageSize: body.size);
        }else if self.msgBodyType == .video {
            self.cellName = "MsgUserVideoCell";
            let body = self.message.body as! EMVideoMessageBody;
            self.imageFitSize = messageCell_imageSizeToFitSize(imageSize: body.thumbnailSize);
        }else if self.msgBodyType == .location {
            self.cellName = "MsgUserLocationCell";
            let body = self.message.body as! EMLocationMessageBody;
            self.text = body.address ?? "未知"
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.addressFont, color: UIColor.black)
            self.textHeight = fitHeight_attributedString(attributedString: show_text, maxWidth: MsgCellOtherLayoutAdapterConfig.share.locationCellMsgContentWidth - (2 * MsgCellOtherLayoutAdapterConfig.share.locationCellTextLeftAndRightSide))
        }else if self.msgBodyType == .voice {
            self.voiceConvertText_status = .none;
            let body = self.message.body as! EMVoiceMessageBody;
            self.voiceDuration = body.duration
            self.cellName = "MsgUserVoiceCell";
        }else if self.msgBodyType == .file {
            self.cellName = "MsgUserFileCell";
        }else if self.msgBodyType == .cmd {
        }else if self.msgBodyType == .custom {
            let body = self.message.body as! EMCustomMessageBody;
            if body.event == "userCard" {
                self.cellName = "EMsgUserBusinessCardCell";
            }else if body.event == "" {
                self.cellName = "MsgUserUnknownCell";
                self.text = "CUSTOM\nevent:\n\(body.event ?? "")\ncustomExt:\n\(body.customExt ?? [:])"
                self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.customDescriptionFont, color: UIColor.black)
                self.textHeight = fitHeight_attributedString(attributedString: show_text, maxWidth: MsgCellLayoutAdapterConfig.share.msgContentMaxWidth())
            }else{
                self.cellName = "MsgUserUnknownCell";
                self.text = "CUSTOM\nevent:\n\(body.event ?? "")\ncustomExt:\n\(body.customExt ?? [:])"
                self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.customDescriptionFont, color: UIColor.black)
                self.textHeight = fitHeight_attributedString(attributedString: show_text, maxWidth: MsgCellLayoutAdapterConfig.share.msgContentMaxWidth())
            }
        }else if self.msgBodyType == .extGif {
            self.cellName = "MsgUserBigEmojiCell";
        }else if self.msgBodyType == .extRecall {
            self.cellName = "MsgSystemRemindCell";
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.systemTextFont, color: UIColor.gray)
            self.textHeight =
            fitHeight_attributedString(attributedString: self.show_text, maxWidth: SCREEN_WIDTH - (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindLeftAndRightMiniEdgeSpacing))
        }else if self.msgBodyType == .extNewFriend {
            self.cellName = "MsgSystemRemindCell";
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.systemTextFont, color: UIColor.gray)
            self.textHeight = fitHeight_attributedString(attributedString: self.show_text, maxWidth: SCREEN_WIDTH - (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindLeftAndRightMiniEdgeSpacing))
        }else if self.msgBodyType == .extAddGroup {
            self.cellName = "MsgSystemRemindCell";
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.systemTextFont, color: UIColor.gray)
            self.textHeight = fitHeight_attributedString(attributedString: self.show_text, maxWidth: SCREEN_WIDTH - (2 * MsgCellOtherLayoutAdapterConfig.share.systemRemindLeftAndRightMiniEdgeSpacing))
        }else if self.msgBodyType == .extCall {
        }else if self.msgBodyType == .pictMixText {
        }else{
            self.cellName = "MsgUserUnknownCell";
            self.text = "不知道这个是什么类型的消息"
            self.show_text = attributedString(string: text, font: MsgTableViewConfig.share.customDescriptionFont, color: UIColor.black)
            self.textHeight = fitHeight_attributedString(attributedString: show_text, maxWidth: MsgCellLayoutAdapterConfig.share.msgContentMaxWidth())
        }
    }
    
    func statusChanged(){
        rx_messageStatus.onNext(message.status)
    }
}










extension MsgCellBaseModel {
    
//    func playVoice(){
//    }
    
    func startVoickConvertText(){
        self.voiceConvertText_tempText = ""
        self.voiceConvertText_reloading = false
        self.voiceConvertText_status = .converting
        self.voiceConvertText_tempText = "转换中..."
        let body = self.message.body
        var voiceBody : EMVoiceMessageBody
        if body is EMVoiceMessageBody {
            voiceBody = body as! EMVoiceMessageBody
        }else{
            print("无法进行语音转文字,因为message.body不正确")
            return
        }
        let path = file_fetchVoickWAVFilePath(filePath: voiceBody.localPath)
        if path.count > 0 {
            JJVoiceConvertWordHelper.share.addVoiceFileConvertWordTask(filePath: path) {[unowned self] transcription in
                //
                self.voiceConvertText_tempText = transcription.formattedString
                    
                RunLoop.current.cancelPerform(#selector(_voiceToConvertReloadTableViewCell), target: self, argument: nil)
                RunLoop.current.perform(#selector(_voiceToConvertReloadTableViewCell), target: self, argument: nil, order: 10, modes: [.default])
            } completion: {[unowned self] result, error in
                self.voiceConvertText_status = .success
                if let result {
                    self.voiceConvertText_tempText = result.bestTranscription.formattedString
                }else{
                    self.voiceConvertText_status = .failure
                    self.voiceConvertText_tempText = "转换失败!!!"
                }
                RunLoop.current.cancelPerform(#selector(_voiceToConvertReloadTableViewCell), target: self, argument: nil)
                RunLoop.current.perform(#selector(_voiceToConvertReloadTableViewCell), target: self, argument: nil, order: 10, modes: [.default])
            }
        }else{
            print("文件问题")
            self.voiceConvertText_status = .failure
            self.voiceConvertText_tempText = "转换失败!!!"
        }
        RunLoop.current.perform(#selector(_voiceToConvertReloadTableViewCell), target: self, argument: nil, order: 10, modes: [.default])
    }
    
    @objc func _voiceToConvertReloadTableViewCell(){
        if voiceConvertText_reloading {
            return
        }
        voiceConvertText_reloading = true
        _voice_runReloading()
    }
    func _voice_runReloading(){
        if self.voiceConvertText_tempText.count == 0 {
            self.voiceConvertText_reloading = false
            return
        }
        if let cell = self.currentCell {
            self.text = self.voiceConvertText_tempText
            self.voiceConvertText_tempText = ""
            cell.currentTableView?.performBatchUpdates({
                
            },completion: { [unowned self] finished in
                cell.currentTableView?.reloadRows(at: [cell.currentIndexPath], with: .none)
                guard let cellRect = cell.currentTableView?.rectForRow(at: cell.currentIndexPath) else {
                    return
                }
                guard let tableView = cell.currentTableView else {
                    return
                }
                if (cellRect.origin.y + cellRect.size.height) > (tableView.contentOffset.y + tableView.frame.height) {
                    cell.currentTableView?.scrollToRow(at: cell.currentIndexPath, at: .bottom, animated: true)
                }

                self._voice_runReloading()
            })
        }
    }
}
